/*
* Software License Agreement (BSD License)
* Copyright (c) 2013, Georgia Institute of Technology
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE

* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**********************************************
 * @file main_window.hpp
 * @author Brian Goldfain <bgoldfai@gmail.com>
 * @date March 3, 2012
 * @copyright 2012 Georgia Institute of Technology
 * @brief QT Based OCS main window
 *
 * @details This file contains the MainWindow class that utilizes main_window.ui
 * to generate an Operator Control Station (OCS) GUI. The GUI provides a window
 * into various ROS messages and the ability to disable vehicle motion using the
 * runstop message. This class was built from a template generated by qt-ros
 ***********************************************/
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H

#include <QtGui/QMainWindow>
#include <QtCore/QTimer>
#include "ui_main_window.h"
#include "qnode.hpp"

/**
 * @class MainWindow main_window.hpp "ocs/main_window.hpp"
 * @brief Operator Control Station GUI developed in QT
 * @note this code grows orgnaically (its dirty)
 */
class MainWindow : public QMainWindow {
Q_OBJECT

public:
	MainWindow(int argc, char** argv, QWidget *parent = 0);
	~MainWindow();

	void ReadSettings(); // Load up qt program settings at startup
	void WriteSettings(); // Save qt program settings when closing

	void closeEvent(QCloseEvent *event); // Overloaded function

public slots:
	/**
  * @brief Slot for OCS menu action
  */
	void on_actionAbout_triggered();
	
	void on_imageTopicsRefresh_button_clicked();
	
	void on_saveImages_button_clicked();
	
	void on_imageTopics_comboBox_currentIndexChanged(int index);
	
	void on_imageTopics_comboBox_2_currentIndexChanged(int index);

  void on_pushButton_saveLeft_clicked();
  void on_pushButton_saveRight_clicked();

	/**
  * @brief Slot that is activated when the enableMotion button is presses
  * @param check The state of the button
  */
  void enableMotion(const bool check);


	/**
  * @brief Slot used to trigger display updates
  */
  void updateTimeBoxes();

  //void updateLoggingView(); // no idea why this can't connect automatically

  /**
  * @brief Update OCS with the new wheelSpeeds
  * @param msg The new wheelSpeeds
  */
  void updateWheelSpeeds(const autorally_msgs::wheelSpeedsConstPtr& msg);

  /**
  * @brief Update OCS with new chassis data
  * @param msg The new servo data
  */
  void updateActuatorData(const autorally_msgs::chassisStateConstPtr& msg);

  void setEnableLabel(QLabel* label, bool enabled);

  void setControl(bool check);
  void sendChassisCommand();

  /**
  * @brief Desired steering value has been changed
  * @param val The new steering value
  */
  void setSteering(const int val);

  /**
  * @brief Desired throttle value has been changed
  * @param val The new throttle value
  */
  void setThrottle(const int val);

  /**
  * @brief Desired front brake value has been changed
  * @param val The new front brake value
  */
  void setFrontBrake(const int val);

  void currentTabChanged(const int index);

  void updateImage1();
  void updateImage2();

private:
	Ui::MainWindowDesign ui; ///> Design file for the GUI
	QNode qnode; ///> Provides access to the ROS system
	ros::Time m_startTime; ///> Time OCS started
  autorally_msgs::chassisCommand m_chassisCommand; ///> servoInterfaceCommand message
  QTimer m_diagTimeTimer; ///> Timer to trigger color updates
  QTimer m_updateTimeBoxesTimer; ///> Timer to update displayed elapsed time
  QTimer m_chassisCommandTimer; ///< Timer for sending servo command messages
  std::string m_progrssBarLevelStyleSheets[3]; ///> List of style sheets for the QProgressBars
  bool m_savingImages;
  int m_saveOneImage;

  /**
  * @brief Computes a status based on a value and 2 thresholds
  * @param warnVal Threshold value to be considered abnormal
  * @param critVal Threshold value to be considered critical
  * @param val
  * @return level 0=OK, 1=WARN, 2=ERROR. Follows the levels from ros diagnostics
  *
  * Computes the status of a given state variable given warning and critical
  * thresholds for that value. The level computed follows those in
  * ros::diagnostic_msgs::DiagnosticStatus. Can handle values that are critical
  * when high such as temp and values that are critical when low such as battery
  */
  template <class T>
  unsigned char levelFromParams(const T warnVal, const T critVal, const T val) const;

  /**
  * @brief Slot indicating if the OCS wants to control the car
  * @param msg the desired servo positions commanded by the OCS
  */
  void setControl(autorally_msgs::chassisCommand& msg);
};

#endif // ocs_MAIN_WINDOW_H
